﻿namespace DesignModeConsole.行为型.模板模式;

/*
 * 模板模式作用之一 代码复用
 * 当一个算法逻辑里面的代码基本相同，那么就可以将其拆分为多个方法，然后将公共代码抽离到基类中，子类继承基类重写不同的代码
 * 
 */

/// <summary>
/// 未拆分时候的逻辑
/// </summary>
public class OldClass
{
    public void Run(int i)
    {
        Console.WriteLine("进行一些公共的逻辑处理代码");

        if (i == 1)
        {
            Console.WriteLine("处理i等于1的时候逻辑");
        }
        else if (i == 2)
        {
            Console.WriteLine("处理i等于2的时候逻辑");
        }
    }
}

/// <summary>
/// 拆分后逻辑
/// </summary>
public class NewClass
{
    public void Run(int i)
    {
        if (i == 1)
        {
            AbstractClass abstractClass = new ConcreteClass1();
            abstractClass.Run();
        }
        else if (i == 2)
        {
            AbstractClass abstractClass = new ConcreteClass2();
            abstractClass.Run();
        }
    }
}

/// <summary>
/// 将公有代码抽取到基类中
/// </summary>
public abstract class AbstractClass
{
    /// <summary>
    /// 模板方法，不要把模版方法定义为Virtual或abstract方法，避免被子类重写，防止更改流程的执行顺序
    /// </summary>
    public void Run()
    {
        Method0();
        Method1();
        Method2();
    }

    private void Method0()
    {
        // 避免子类重写它
        Console.WriteLine("进行一些公共的逻辑处理代码");
    }

    // 定义抽象方法是为了强迫子类去实现
    protected abstract void Method1();
    protected abstract void Method2();
}

/// <summary>
/// 子类实现
/// </summary>
public class ConcreteClass1 : AbstractClass
{
    protected override void Method1()
    {
        // 实现父类Method1方法
        Console.WriteLine("处理i等于1的时候逻辑 Method1");
    }

    // 实现父类Method2方法
    protected override void Method2()
    {
        Console.WriteLine("处理i等于1的时候逻辑 Method2");
    }
}

/// <summary>
/// 实现类2
/// </summary>
public class ConcreteClass2 : AbstractClass
{
    protected override void Method1()
    {
        Console.WriteLine("处理i等于2的时候逻辑 Method1");
    }

    protected override void Method2()
    {
        Console.WriteLine("处理i等于2的时候逻辑 Method2");
    }
}